package controllers

import (
	"bytes"
	"encoding/csv"
	"github.com/360EntSecGroup-Skylar/excelize"
	"github.com/astaxie/beego"
	"math"
	"net/url"
	"nspel/entity"
	"nspel/lock"
	"nspel/model"
	"nspel/nspel"
	"nspel/util"
	"strconv"
)

type PhysicalManageController struct {
	beego.Controller
}

func (c *PhysicalManageController) PostPhysicalImportCheck() {
	defer c.ServeJSON()
	requestData := new(model.PostPhysicalImportSubmit)
	school, err := requestData.Validate(&c.Controller)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
		return
	}
	excelData, err := util.TryParseXlsx(&requestData.ImportFile)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
		return
	}
	msg, _, _, _, _, _, err := util.ValidatePhysicalImport(&excelData, school, requestData.MeasureDate)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	c.Data["json"] = msg
}

func (c *PhysicalManageController) PostPhysicalImportSubmit() {
	defer c.ServeJSON()
	requestData := new(model.PostPhysicalImportSubmit)
	school, err := requestData.Validate(&c.Controller)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
		return
	}
	excelData, err := util.TryParseXlsx(&requestData.ImportFile)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
		return
	}
	msg, createStudent, createScore, updateStudent, create, update, err := util.ValidatePhysicalImport(&excelData, school, requestData.MeasureDate)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	if msg.Result {
		err = util.ScoreImport(school, &createStudent, &createScore, &updateStudent, &create, &update, requestData.MeasureDate)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		lock.PhysicalImportLock.Lock()
		err = util.InitReport(school, &createScore, &create, &update, requestData.MeasureDate)
		lock.PhysicalImportLock.Unlock()
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
	}
	c.Data["json"] = msg
}

func (c *PhysicalManageController) GetVisualizationData() {
	authority, ok := c.Ctx.Input.Session("authority").(byte)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 1, Msg: "session失效"}
		c.ServeJSON()
		return
	}
	uid, ok := c.Ctx.Input.Session("uid").(int64)
	if !ok {
		c.Data["json"] = model.ErrorRes{RetCode: 1, Msg: "session失效"}
		c.ServeJSON()
		return
	}
	var schoolId int64
	var schoolType byte
	var err error
	if authority == entity.ManagerAuthority.Administrator || authority == entity.ManagerAuthority.Area {
		schoolId, err = c.GetInt64("school-id")
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
			c.ServeJSON()
			return
		}
		school := new(entity.School)
		err = school.SelectAllById(schoolId)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			c.ServeJSON()
			return
		}
		schoolType = school.SchoolType
		if authority == entity.ManagerAuthority.Area {
			area := new(entity.Area)
			err = area.SelectAllByUserId(uid)
			if err != nil {
				c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
				nspel.Error(err)
				c.ServeJSON()
				return
			}
			if school.ExperimentAreaId != area.Id {
				c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
				c.ServeJSON()
				return
			}
		}
	} else if authority == entity.ManagerAuthority.School {
		school := new(entity.School)
		err = school.SelectAllByUserId(uid)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			c.ServeJSON()
			return
		}
		schoolId = school.Id
		schoolType = school.SchoolType
	}
	csvData := new(bytes.Buffer)
	csvGenerator := csv.NewWriter(csvData)
	if entity.SchoolTypeMapCode[schoolType] == "小" {
		csvGenerator.Write([]string{"年级", "班级", "性别(1男2女)", "身高(cm)", "体重(kg)", "体重指数", "肺活量(ml)", "50米跑(s)", "坐位体前屈(cm)", "一分钟跳绳(个)", "一分钟仰卧起坐(个)", "50米×8往返跑(s)", "体重等级", "肺活量等级", "50米跑等级", "体前屈等级", "跳绳等级", "仰卧起坐等级", "往返跑等级", "总成绩", "评定等级", "group"})
		score := new(entity.Score)
		scores, err := score.SelectAllBySchoolId(schoolId)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			c.ServeJSON()
			return
		}
		for i := 0; i < len(scores); i++ {
			strBuf := make([]string, 22)
			strBuf[0] = scores[i].Grade[1:2]
			class, _ := strconv.ParseInt(scores[i].Class[5:7], 10, 64)
			strBuf[1] = strconv.FormatInt(class, 10)
			strBuf[2] = strconv.FormatInt(int64(scores[i].Sex), 10)
			if scores[i].Height.Valid {
				strBuf[3] = strconv.FormatFloat(scores[i].Height.Float64, 'f', -1, 64)
			} else {
				strBuf[3] = "-1"
			}
			if scores[i].Weight.Valid {
				strBuf[4] = strconv.FormatFloat(scores[i].Weight.Float64, 'f', -1, 64)
			} else {
				strBuf[4] = "-1"
			}
			if scores[i].BodyMassIndex.Valid {
				strBuf[5] = strconv.FormatFloat(scores[i].BodyMassIndex.Float64, 'f', -1, 64)
			} else {
				strBuf[5] = "-1"
			}
			if scores[i].VitalCapacity.Valid {
				strBuf[6] = strconv.FormatFloat(scores[i].VitalCapacity.Float64, 'f', -1, 64)
			} else {
				strBuf[6] = "-1"
			}
			if scores[i].FiftyMeters.Valid {
				strBuf[7] = strconv.FormatFloat(scores[i].FiftyMeters.Float64, 'f', -1, 64)
			} else {
				strBuf[7] = "-1"
			}
			if scores[i].SitAndReach.Valid {
				strBuf[8] = strconv.FormatFloat(scores[i].SitAndReach.Float64, 'f', -1, 64)
			} else {
				strBuf[8] = "-1"
			}
			if scores[i].OneMinuteRopeSkipping.Valid {
				strBuf[9] = strconv.FormatFloat(scores[i].OneMinuteRopeSkipping.Float64, 'f', -1, 64)
			} else {
				strBuf[9] = "-1"
			}
			if scores[i].OneMinuteSitUp.Valid {
				strBuf[10] = strconv.FormatFloat(scores[i].OneMinuteSitUp.Float64, 'f', -1, 64)
			} else {
				strBuf[10] = "-1"
			}
			if scores[i].ShuttleRun.Valid {
				strBuf[11] = strconv.FormatFloat(scores[i].ShuttleRun.Float64, 'f', -1, 64)
			} else {
				strBuf[11] = "-1"
			}
			strBuf[12] = util.LevelClassification(scores[i].BodyMassIndexLevel.String, "肥胖", "超重", "正常", "低体重", "4", "3", "2", "1", "-1").(string)
			strBuf[13] = util.LevelClassification(scores[i].VitalCapacityLevel.String, "优秀", "良好", "及格", "不及格", "4", "3", "2", "1", "-1").(string)
			strBuf[14] = util.LevelClassification(scores[i].FiftyMetersLevel.String, "优秀", "良好", "及格", "不及格", "4", "3", "2", "1", "-1").(string)
			strBuf[15] = util.LevelClassification(scores[i].SitAndReachLevel.String, "优秀", "良好", "及格", "不及格", "4", "3", "2", "1", "-1").(string)
			strBuf[16] = util.LevelClassification(scores[i].OneMinuteRopeSkippingLevel.String, "优秀", "良好", "及格", "不及格", "4", "3", "2", "1", "-1").(string)
			strBuf[17] = util.LevelClassification(scores[i].OneMinuteSitUpLevel.String, "优秀", "良好", "及格", "不及格", "4", "3", "2", "1", "-1").(string)
			strBuf[18] = util.LevelClassification(scores[i].ShuttleRunLevel.String, "优秀", "良好", "及格", "不及格", "4", "3", "2", "1", "-1").(string)
			strBuf[19] = strconv.FormatFloat(scores[i].PhysicalTotalScore.Float64, 'f', -1, 64)
			strBuf[20] = util.LevelClassification(scores[i].PhysicalLevel.String, "优秀", "良好", "及格", "不及格", "4", "3", "2", "1", "-1").(string)
			grade, _ := strconv.ParseInt(strBuf[0], 10, 64)
			strBuf[21] = util.IntToChinese(int(grade)) + "年级" + util.IntToChinese(int(class)) + "班"
			csvGenerator.Write(strBuf)
		}
	}
	c.Ctx.Output.Header("Content-Disposition", "attachment; filename="+url.PathEscape("数据可视化.csv"))
	c.Ctx.Output.Header("Content-Description", "File Transfer")
	c.Ctx.Output.Header("Content-Type", "application/octet-stream")
	c.Ctx.Output.Header("Content-Transfer-Encoding", "binary")
	c.Ctx.Output.Header("Expires", "0")
	c.Ctx.Output.Header("Cache-Control", "must-revalidate")
	c.Ctx.Output.Header("Pragma", "public")
	c.Ctx.ResponseWriter.Write(csvData.Bytes())
}

func (c *PhysicalManageController) GetPhysicalList() {
	defer c.ServeJSON()
	req := model.GetPhysicalListReq{}
	b := req.Validate("province-id", "city-id", "area-id", "school-name", "join-year", "school-roll-id", "page-size", "current-page", &c.Controller)
	if !b {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
		return
	}
	count, scores, err := util.GetPhysicalList(req.ProvinceId, req.CityId, req.AreaId, req.SchoolName, req.JoinYear, req.SchoolRollId, req.PageSize, req.CurrentPage)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
		nspel.Error(err)
		return
	}
	res := model.GetPhysicalListRes{RetCode: 0}
	res.Total = int64(count)
	res.Data = make([]model.PhysicalList, len(scores))
	for i := 0; i < len(scores); i++ {
		res.Data[i].Id = scores[i].Id
		res.Data[i].SchoolRollId = scores[i].SchoolRollId
		student := new(entity.Student)
		err := student.SelectAllBySchoolRollId(res.Data[i].SchoolRollId)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		res.Data[i].Name = student.Name
		if student.Sex == 1 {
			res.Data[i].Sex = "男"
		} else if student.Sex == 2 {
			res.Data[i].Sex = "女"
		}
		res.Data[i].Grade = util.GetGrade(scores[i].Grade, scores[i].Class)
		res.Data[i].Class = util.GetClass(scores[i].Class)
		school := new(entity.School)
		err = school.SelectAllById(scores[i].SchoolId)
		if err != nil {
			c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行错误"}
			nspel.Error(err)
			return
		}
		res.Data[i].School = school.Name
		res.Data[i].MeasureDate = scores[i].MeasurementDate.Format("2006年01月02日")
		if scores[i].IsExemption {
			res.Data[i].IsExemption = "是"
		} else {
			res.Data[i].IsExemption = "否"
		}
		res.Data[i].MissingTestNum = scores[i].MissingTestNum
		res.Data[i].PhysicalTotalScore = scores[i].PhysicalTotalScore.Float64
		res.Data[i].PhysicalBasicScore = scores[i].PhysicalBasicScore.Float64
		res.Data[i].PhysicalExtraScore = scores[i].PhysicalExtraScore.Float64
		res.Data[i].PhysicalLevel = scores[i].PhysicalLevel.String
		if scores[i].Height.Valid {
			res.Data[i].Height = scores[i].Height.Float64
		} else {
			res.Data[i].Height = ""
		}
		if scores[i].Weight.Valid {
			res.Data[i].Weight = scores[i].Weight.Float64
		} else {
			res.Data[i].Weight = ""
		}
		res.Data[i].AppendItem(&res.Data[i].BodyMassIndex, &res.Data[i].BodyMassIndexBasicScore, &res.Data[i].BodyMassIndexExtraScore, &res.Data[i].BodyMassIndexTotalScore, &res.Data[i].BodyMassIndexLevel, &scores[i].BodyMassIndex, &scores[i].BodyMassIndexBasicScore, &scores[i].BodyMassIndexExtraScore, &scores[i].BodyMassIndexTotalScore, &scores[i].BodyMassIndexLevel)
		res.Data[i].AppendItem(&res.Data[i].VitalCapacity, &res.Data[i].VitalCapacityBasicScore, &res.Data[i].VitalCapacityExtraScore, &res.Data[i].VitalCapacityTotalScore, &res.Data[i].VitalCapacityLevel, &scores[i].VitalCapacity, &scores[i].VitalCapacityBasicScore, &scores[i].VitalCapacityExtraScore, &scores[i].VitalCapacityTotalScore, &scores[i].VitalCapacityLevel)
		res.Data[i].AppendItem(&res.Data[i].FiftyMeters, &res.Data[i].FiftyMetersBasicScore, &res.Data[i].FiftyMetersExtraScore, &res.Data[i].FiftyMetersTotalScore, &res.Data[i].FiftyMetersLevel, &scores[i].FiftyMeters, &scores[i].FiftyMetersBasicScore, &scores[i].FiftyMetersExtraScore, &scores[i].FiftyMetersTotalScore, &scores[i].FiftyMetersLevel)
		res.Data[i].AppendItem(&res.Data[i].SitAndReach, &res.Data[i].SitAndReachBasicScore, &res.Data[i].SitAndReachExtraScore, &res.Data[i].SitAndReachTotalScore, &res.Data[i].SitAndReachLevel, &scores[i].SitAndReach, &scores[i].SitAndReachBasicScore, &scores[i].SitAndReachExtraScore, &scores[i].SitAndReachTotalScore, &scores[i].SitAndReachLevel)
		res.Data[i].AppendItem(&res.Data[i].OneMinuteRopeSkipping, &res.Data[i].OneMinuteRopeSkippingBasicScore, &res.Data[i].OneMinuteRopeSkippingExtraScore, &res.Data[i].OneMinuteRopeSkippingTotalScore, &res.Data[i].OneMinuteRopeSkippingLevel, &scores[i].OneMinuteRopeSkipping, &scores[i].OneMinuteRopeSkippingBasicScore, &scores[i].OneMinuteRopeSkippingExtraScore, &scores[i].OneMinuteRopeSkippingTotalScore, &scores[i].OneMinuteRopeSkippingLevel)
		res.Data[i].AppendItem(&res.Data[i].OneMinuteSitUps, &res.Data[i].OneMinuteSitUpsBasicScore, &res.Data[i].OneMinuteSitUpsExtraScore, &res.Data[i].OneMinuteSitUpsTotalScore, &res.Data[i].OneMinuteSitUpsLevel, &scores[i].OneMinuteSitUp, &scores[i].OneMinuteSitUpBasicScore, &scores[i].OneMinuteSitUpExtraScore, &scores[i].OneMinuteSitUpTotalScore, &scores[i].OneMinuteSitUpLevel)
		res.Data[i].AppendItem(&res.Data[i].ShuttleRun, &res.Data[i].ShuttleRunBasicScore, &res.Data[i].ShuttleRunExtraScore, &res.Data[i].ShuttleRunTotalScore, &res.Data[i].ShuttleRunLevel, &scores[i].ShuttleRun, &scores[i].ShuttleRunBasicScore, &scores[i].ShuttleRunExtraScore, &scores[i].ShuttleRunTotalScore, &scores[i].ShuttleRunLevel)
		res.Data[i].AppendItem(&res.Data[i].StandingLongJump, &res.Data[i].StandingLongJumpBasicScore, &res.Data[i].StandingLongJumpExtraScore, &res.Data[i].StandingLongJumpTotalScore, &res.Data[i].StandingLongJumpLevel, &scores[i].StandingLongJump, &scores[i].StandingLongJumpBasicScore, &scores[i].StandingLongJumpExtraScore, &scores[i].StandingLongJumpTotalScore, &scores[i].StandingLongJumpLevel)
		res.Data[i].AppendItem(&res.Data[i].Chinning, &res.Data[i].ChinningBasicScore, &res.Data[i].ChinningExtraScore, &res.Data[i].ChinningTotalScore, &res.Data[i].ChinningLevel, &scores[i].Chinning, &scores[i].ChinningBasicScore, &scores[i].ChinningExtraScore, &scores[i].ChinningTotalScore, &scores[i].ChinningLevel)
		res.Data[i].AppendItem(&res.Data[i].OneThousandMeters, &res.Data[i].OneThousandMetersBasicScore, &res.Data[i].OneThousandMetersExtraScore, &res.Data[i].OneThousandMetersTotalScore, &res.Data[i].OneThousandMetersLevel, &scores[i].OneThousandMeters, &scores[i].OneThousandMetersBasicScore, &scores[i].OneThousandMetersExtraScore, &scores[i].OneThousandMetersTotalScore, &scores[i].OneThousandMetersLevel)
		res.Data[i].AppendItem(&res.Data[i].EightHundredMeters, &res.Data[i].EightHundredMetersBasicScore, &res.Data[i].EightHundredMetersExtraScore, &res.Data[i].EightHundredMetersTotalScore, &res.Data[i].EightHundredMetersLevel, &scores[i].EightHundredMeters, &scores[i].EightHundredMetersBasicScore, &scores[i].EightHundredMetersExtraScore, &scores[i].EightHundredMetersTotalScore, &scores[i].EightHundredMetersLevel)
		res.Data[i].AppendExtra(&res.Data[i].BodyFat, &res.Data[i].BodyFatLevel, &scores[i].BodyFat, &scores[i].BodyFatLevel)
		res.Data[i].AppendExtra(&res.Data[i].Grip, &res.Data[i].GripLevel, &scores[i].GripStrength, &scores[i].GripStrengthLevel)
		res.Data[i].AppendExtra(&res.Data[i].ResponseCapability, &res.Data[i].ResponseCapabilityLevel, &scores[i].ResponseCapability, &scores[i].ResponseCapabilityLevel)
		res.Data[i].AppendExtra(&res.Data[i].BalanceAbility, &res.Data[i].BalanceAbilityLevel, &scores[i].BalanceAbility, &scores[i].BalanceAbilityLevel)
		res.Data[i].AppendExtra(&res.Data[i].VerticalJump, &res.Data[i].VerticalJumpLevel, &scores[i].VerticalJump, &scores[i].VerticalJumpLevel)
	}
	c.Data["json"] = res
}

func (c *PhysicalManageController) PostPhysicalModify() {
	defer c.ServeJSON()
	req := model.PostPhysicalModifyReq{}
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
		return
	}
	b, err, score := req.Validate()
	if err != nil {
		nspel.Error(err)
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行出错"}
		return
	}
	if !b {
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "请求无效"}
		return
	}
	err = score.Update("class", "grade", "height", "weight", "body_mass_index", "body_mass_index_basic_score", "body_mass_index_extra_score", "body_mass_index_total_score", "body_mass_index_level", "vital_capacity", "vital_capacity_basic_score", "vital_capacity_extra_score", "vital_capacity_total_score", "vital_capacity_level", "50_meters", "50_meters_basic_score", "50_meters_extra_score", "50_meters_total_score", "50_meters_level", "sit_and_reach", "sit_and_reach_basic_score", "sit_and_reach_extra_score", "sit_and_reach_total_score", "sit_and_reach_level", "1_minute_rope_skipping", "1_minute_rope_skipping_basic_score", "1_minute_rope_skipping_extra_score", "1_minute_rope_skipping_total_score", "1_minute_rope_skipping_level", "1_minute_sit_up", "1_minute_sit_up_basic_score", "1_minute_sit_up_extra_score", "1_minute_sit_up_total_score", "1_minute_sit_up_level", "shuttle_run", "shuttle_run_basic_score", "shuttle_run_extra_score", "shuttle_run_total_score", "shuttle_run_level", "standing_long_jump", "standing_long_jump_basic_score", "standing_long_jump_extra_score", "standing_long_jump_total_score", "standing_long_jump_level", "chinning", "chinning_basic_score", "chinning_extra_score", "chinning_total_score", "chinning_level", "1000_meters", "1000_meters_basic_score", "1000_meters_extra_score", "1000_meters_total_score", "1000_meters_level", "800_meters", "800_meters_basic_score", "800_meters_extra_score", "800_meters_total_score", "800_meters_level", "physical_basic_score", "physical_extra_score", "physical_total_score", "physical_level", "body_fat", "body_fat_level", "grip_strength", "grip_strength_level", "response_capability", "response_capability_level", "balance_ability", "balance_ability_level", "vertical_jump", "vertical_jump_level", "is_exemption", "missing_test_num", "measurement_date")
	if err != nil {
		nspel.Error(err)
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行出错"}
		return
	}
	nspel.RedisKeyDelete("student")
	nspel.RedisKeyDelete("score")
	err = util.UpdateSchoolScore(score.Id)
	if err != nil {
		nspel.Error(err)
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行出错"}
		return
	}
	err = util.UpdateAreaScore(score.ExperimentAreaId)
	if err != nil {
		nspel.Error(err)
		c.Data["json"] = model.ErrorRes{RetCode: 2, Msg: "服务器运行出错"}
		return
	}
	c.Data["json"] = map[string]interface{}{"retCode": 0, "msg": "更新成功"}
	return
}

func (c *PhysicalManageController) GetPhysicalExport() {
	c.EnableRender = false
	req := model.GetPhysicalExportReq{}
	b := req.Validate("province-id", "city-id", "area-id", "school-name", "join-year", "school-roll-id", &c.Controller)
	if !b {
		c.Ctx.ResponseWriter.Status = 400
		return
	}
	_, scores, err := util.GetPhysicalList(req.ProvinceId, req.CityId, req.AreaId, req.SchoolName, req.JoinYear, req.SchoolRollId, math.MaxInt64, 1)
	if err != nil {
		c.Ctx.ResponseWriter.Status = 500
		nspel.Error(err)
		return
	}
	widthMap := make(map[string]float64)
	xlsx := excelize.NewFile()
	xlsx.SetSheetName("Sheet1", "体质")
	xlsx.SetCellValue("体质", "A1", "学校编码")
	widthMap["A"] = math.Max(widthMap["A"], util.GetStrLength("学校编码")+1)
	xlsx.SetCellValue("体质", "B1", "年级编号")
	widthMap["B"] = math.Max(widthMap["B"], util.GetStrLength("年级编号")+1)
	xlsx.SetCellValue("体质", "C1", "班级编号")
	widthMap["C"] = math.Max(widthMap["C"], util.GetStrLength("班级编号")+1)
	xlsx.SetCellValue("体质", "D1", "学籍号")
	widthMap["D"] = math.Max(widthMap["D"], util.GetStrLength("学籍号")+1)
	xlsx.SetCellValue("体质", "E1", "民族代码")
	widthMap["E"] = math.Max(widthMap["E"], util.GetStrLength("民族代码")+1)
	xlsx.SetCellValue("体质", "F1", "姓名")
	widthMap["F"] = math.Max(widthMap["F"], util.GetStrLength("姓名")+1)
	xlsx.SetCellValue("体质", "G1", "性别")
	widthMap["G"] = math.Max(widthMap["G"], util.GetStrLength("性别")+1)
	xlsx.SetCellValue("体质", "H1", "出生日期")
	widthMap["H"] = math.Max(widthMap["H"], util.GetStrLength("出生日期")+1)
	xlsx.SetCellValue("体质", "I1", "身份证号")
	widthMap["I"] = math.Max(widthMap["I"], util.GetStrLength("身份证号")+1)
	xlsx.SetCellValue("体质", "J1", "学号")
	widthMap["J"] = math.Max(widthMap["J"], util.GetStrLength("学号")+1)
	xlsx.SetCellValue("体质", "K1", "是否补测")
	widthMap["K"] = math.Max(widthMap["K"], util.GetStrLength("是否补测")+1)
	xlsx.SetCellValue("体质", "L1", "是否免测")
	widthMap["L"] = math.Max(widthMap["L"], util.GetStrLength("是否免测")+1)
	xlsx.SetCellValue("体质", "M1", "身高")
	widthMap["M"] = math.Max(widthMap["M"], util.GetStrLength("身高")+1)
	xlsx.SetCellValue("体质", "N1", "体重")
	widthMap["N"] = math.Max(widthMap["N"], util.GetStrLength("体重")+1)
	xlsx.SetCellValue("体质", "O1", "BMI")
	widthMap["O"] = math.Max(widthMap["O"], util.GetStrLength("BMI")+1)
	xlsx.SetCellValue("体质", "P1", "BMI基础分")
	widthMap["P"] = math.Max(widthMap["P"], util.GetStrLength("BMI基础分")+1)
	xlsx.SetCellValue("体质", "Q1", "BMI额外分")
	widthMap["Q"] = math.Max(widthMap["Q"], util.GetStrLength("BMI额外分")+1)
	xlsx.SetCellValue("体质", "R1", "BMI总分")
	widthMap["R"] = math.Max(widthMap["R"], util.GetStrLength("BMI总分")+1)
	xlsx.SetCellValue("体质", "S1", "BMI评价")
	widthMap["S"] = math.Max(widthMap["S"], util.GetStrLength("BMI评价")+1)
	xlsx.SetCellValue("体质", "T1", "肺活量")
	widthMap["T"] = math.Max(widthMap["T"], util.GetStrLength("肺活量")+1)
	xlsx.SetCellValue("体质", "U1", "肺活量基础分")
	widthMap["U"] = math.Max(widthMap["U"], util.GetStrLength("肺活量基础分")+1)
	xlsx.SetCellValue("体质", "V1", "肺活量额外分")
	widthMap["V"] = math.Max(widthMap["V"], util.GetStrLength("肺活量额外分")+1)
	xlsx.SetCellValue("体质", "W1", "肺活量总分")
	widthMap["W"] = math.Max(widthMap["W"], util.GetStrLength("肺活量总分")+1)
	xlsx.SetCellValue("体质", "X1", "肺活量评价")
	widthMap["X"] = math.Max(widthMap["X"], util.GetStrLength("肺活量评价")+1)
	xlsx.SetCellValue("体质", "Y1", "50米跑")
	widthMap["Y"] = math.Max(widthMap["Y"], util.GetStrLength("50米跑")+1)
	xlsx.SetCellValue("体质", "Z1", "50米跑基础分")
	widthMap["Z"] = math.Max(widthMap["Z"], util.GetStrLength("50米跑基础分")+1)
	xlsx.SetCellValue("体质", "AA1", "50米跑额外分")
	widthMap["AA"] = math.Max(widthMap["AA"], util.GetStrLength("50米跑额外分")+1)
	xlsx.SetCellValue("体质", "AB1", "50米跑总分")
	widthMap["AB"] = math.Max(widthMap["AB"], util.GetStrLength("50米跑总分")+1)
	xlsx.SetCellValue("体质", "AC1", "50米跑评价")
	widthMap["AC"] = math.Max(widthMap["AC"], util.GetStrLength("50米跑评价")+1)
	xlsx.SetCellValue("体质", "AD1", "坐位体前屈")
	widthMap["AD"] = math.Max(widthMap["AD"], util.GetStrLength("坐位体前屈")+1)
	xlsx.SetCellValue("体质", "AE1", "坐位体前屈基础分")
	widthMap["AE"] = math.Max(widthMap["AE"], util.GetStrLength("坐位体前屈基础分")+1)
	xlsx.SetCellValue("体质", "AF1", "坐位体前屈额外分")
	widthMap["AF"] = math.Max(widthMap["AF"], util.GetStrLength("坐位体前屈额外分")+1)
	xlsx.SetCellValue("体质", "AG1", "坐位体前屈总分")
	widthMap["AG"] = math.Max(widthMap["AG"], util.GetStrLength("坐位体前屈总分")+1)
	xlsx.SetCellValue("体质", "AH1", "坐位体前屈评价")
	widthMap["AH"] = math.Max(widthMap["AH"], util.GetStrLength("坐位体前屈评价")+1)
	xlsx.SetCellValue("体质", "AI1", "50米×8往返跑")
	widthMap["AI"] = math.Max(widthMap["AI"], util.GetStrLength("50米×8往返跑")+1)
	xlsx.SetCellValue("体质", "AJ1", "50米×8往返跑基础分")
	widthMap["AJ"] = math.Max(widthMap["AJ"], util.GetStrLength("50米×8往返跑基础分")+1)
	xlsx.SetCellValue("体质", "AK1", "50米×8往返跑额外分")
	widthMap["AK"] = math.Max(widthMap["AK"], util.GetStrLength("50米×8往返跑额外分")+1)
	xlsx.SetCellValue("体质", "AL1", "50米×8往返跑总分")
	widthMap["AL"] = math.Max(widthMap["AL"], util.GetStrLength("50米×8往返跑总分")+1)
	xlsx.SetCellValue("体质", "AM1", "50米×8往返跑评价")
	widthMap["AM"] = math.Max(widthMap["AM"], util.GetStrLength("50米×8往返跑评价")+1)
	xlsx.SetCellValue("体质", "AN1", "1分钟仰卧起坐")
	widthMap["AN"] = math.Max(widthMap["AN"], util.GetStrLength("1分钟仰卧起坐")+1)
	xlsx.SetCellValue("体质", "AO1", "1分钟仰卧起坐基础分")
	widthMap["AO"] = math.Max(widthMap["AO"], util.GetStrLength("1分钟仰卧起坐基础分")+1)
	xlsx.SetCellValue("体质", "AP1", "1分钟仰卧起坐额外分")
	widthMap["AP"] = math.Max(widthMap["AP"], util.GetStrLength("1分钟仰卧起坐额外分")+1)
	xlsx.SetCellValue("体质", "AQ1", "1分钟仰卧起坐总分")
	widthMap["AQ"] = math.Max(widthMap["AQ"], util.GetStrLength("1分钟仰卧起坐总分")+1)
	xlsx.SetCellValue("体质", "AR1", "1分钟仰卧起坐评价")
	widthMap["AR"] = math.Max(widthMap["AR"], util.GetStrLength("1分钟仰卧起坐评价")+1)
	xlsx.SetCellValue("体质", "AS1", "1分钟跳绳")
	widthMap["AS"] = math.Max(widthMap["AS"], util.GetStrLength("1分钟跳绳")+1)
	xlsx.SetCellValue("体质", "AT1", "1分钟跳绳基础分")
	widthMap["AT"] = math.Max(widthMap["AT"], util.GetStrLength("1分钟跳绳基础分")+1)
	xlsx.SetCellValue("体质", "AU1", "1分钟跳绳额外分")
	widthMap["AU"] = math.Max(widthMap["AU"], util.GetStrLength("1分钟跳绳额外分")+1)
	xlsx.SetCellValue("体质", "AV1", "1分钟跳绳总分")
	widthMap["AV"] = math.Max(widthMap["AV"], util.GetStrLength("1分钟跳绳总分")+1)
	xlsx.SetCellValue("体质", "AW1", "1分钟跳绳评价")
	widthMap["AW"] = math.Max(widthMap["AW"], util.GetStrLength("1分钟跳绳评价")+1)
	xlsx.SetCellValue("体质", "AX1", "立定跳远")
	widthMap["AX"] = math.Max(widthMap["AX"], util.GetStrLength("立定跳远")+1)
	xlsx.SetCellValue("体质", "AY1", "立定跳远基础分")
	widthMap["AY"] = math.Max(widthMap["AY"], util.GetStrLength("立定跳远基础分")+1)
	xlsx.SetCellValue("体质", "AZ1", "立定跳远额外分")
	widthMap["AZ"] = math.Max(widthMap["AZ"], util.GetStrLength("立定跳远额外分")+1)
	xlsx.SetCellValue("体质", "BA1", "立定跳远总分")
	widthMap["BA"] = math.Max(widthMap["BA"], util.GetStrLength("立定跳远总分")+1)
	xlsx.SetCellValue("体质", "BB1", "立定跳远评价")
	widthMap["BB"] = math.Max(widthMap["BB"], util.GetStrLength("立定跳远评价")+1)
	xlsx.SetCellValue("体质", "BC1", "800米跑")
	widthMap["BC"] = math.Max(widthMap["BC"], util.GetStrLength("800米跑")+1)
	xlsx.SetCellValue("体质", "BD1", "800米跑基础分")
	widthMap["BD"] = math.Max(widthMap["BD"], util.GetStrLength("800米跑基础分")+1)
	xlsx.SetCellValue("体质", "BE1", "800米跑额外分")
	widthMap["BE"] = math.Max(widthMap["BE"], util.GetStrLength("800米跑额外分")+1)
	xlsx.SetCellValue("体质", "BF1", "800米跑总分")
	widthMap["BF"] = math.Max(widthMap["BF"], util.GetStrLength("800米跑总分")+1)
	xlsx.SetCellValue("体质", "BG1", "800米跑评价")
	widthMap["BG"] = math.Max(widthMap["BG"], util.GetStrLength("800米跑评价")+1)
	xlsx.SetCellValue("体质", "BH1", "1000米跑")
	widthMap["BH"] = math.Max(widthMap["BH"], util.GetStrLength("1000米跑")+1)
	xlsx.SetCellValue("体质", "BI1", "1000米跑基础分")
	widthMap["BI"] = math.Max(widthMap["BI"], util.GetStrLength("1000米跑基础分")+1)
	xlsx.SetCellValue("体质", "BJ1", "1000米跑额外分")
	widthMap["BJ"] = math.Max(widthMap["BJ"], util.GetStrLength("1000米跑额外分")+1)
	xlsx.SetCellValue("体质", "BK1", "1000米跑总分")
	widthMap["BK"] = math.Max(widthMap["BK"], util.GetStrLength("1000米跑总分")+1)
	xlsx.SetCellValue("体质", "BL1", "1000米跑评价")
	widthMap["BL"] = math.Max(widthMap["BL"], util.GetStrLength("1000米跑评价")+1)
	xlsx.SetCellValue("体质", "BM1", "引体向上")
	widthMap["BM"] = math.Max(widthMap["BM"], util.GetStrLength("引体向上")+1)
	xlsx.SetCellValue("体质", "BN1", "引体向上基础分")
	widthMap["BN"] = math.Max(widthMap["BN"], util.GetStrLength("引体向上基础分")+1)
	xlsx.SetCellValue("体质", "BO1", "引体向上额外分")
	widthMap["BO"] = math.Max(widthMap["BO"], util.GetStrLength("引体向上额外分")+1)
	xlsx.SetCellValue("体质", "BP1", "引体向上总分")
	widthMap["BP"] = math.Max(widthMap["BP"], util.GetStrLength("引体向上总分")+1)
	xlsx.SetCellValue("体质", "BQ1", "引体向上评价")
	widthMap["BQ"] = math.Max(widthMap["BQ"], util.GetStrLength("引体向上评价")+1)
	xlsx.SetCellValue("体质", "BR1", "体脂百分比")
	widthMap["BR"] = math.Max(widthMap["BR"], util.GetStrLength("体脂百分比")+1)
	xlsx.SetCellValue("体质", "BS1", "体脂百分比评价")
	widthMap["BS"] = math.Max(widthMap["BS"], util.GetStrLength("体脂百分比评价")+1)
	xlsx.SetCellValue("体质", "BT1", "握力")
	widthMap["BT"] = math.Max(widthMap["BT"], util.GetStrLength("握力")+1)
	xlsx.SetCellValue("体质", "BU1", "握力评价")
	widthMap["BU"] = math.Max(widthMap["BU"], util.GetStrLength("握力评价")+1)
	xlsx.SetCellValue("体质", "BV1", "反应能力")
	widthMap["BV"] = math.Max(widthMap["BV"], util.GetStrLength("反应能力")+1)
	xlsx.SetCellValue("体质", "BW1", "反应能力评价")
	widthMap["BW"] = math.Max(widthMap["BW"], util.GetStrLength("反应能力评价")+1)
	xlsx.SetCellValue("体质", "BX1", "平衡能力")
	widthMap["BX"] = math.Max(widthMap["BX"], util.GetStrLength("平衡能力")+1)
	xlsx.SetCellValue("体质", "BY1", "平衡能力评价")
	widthMap["BY"] = math.Max(widthMap["BY"], util.GetStrLength("平衡能力评价")+1)
	xlsx.SetCellValue("体质", "BZ1", "纵跳")
	widthMap["BZ"] = math.Max(widthMap["BZ"], util.GetStrLength("纵跳")+1)
	xlsx.SetCellValue("体质", "CA1", "纵跳评价")
	widthMap["CA"] = math.Max(widthMap["CA"], util.GetStrLength("纵跳评价")+1)
	xlsx.SetCellValue("体质", "CB1", "基础分数")
	widthMap["CB"] = math.Max(widthMap["CB"], util.GetStrLength("基础分数")+1)
	xlsx.SetCellValue("体质", "CC1", "额外分数")
	widthMap["CC"] = math.Max(widthMap["CC"], util.GetStrLength("额外分数")+1)
	xlsx.SetCellValue("体质", "CD1", "总分数")
	widthMap["CD"] = math.Max(widthMap["CD"], util.GetStrLength("总分数")+1)
	xlsx.SetCellValue("体质", "CE1", "缺测数量")
	widthMap["CE"] = math.Max(widthMap["CE"], util.GetStrLength("缺测数量")+1)
	for i := 0; i < len(scores); i++ {
		school := new(entity.School)
		err = school.SelectAllById(scores[i].SchoolId)
		if err != nil {
			c.Ctx.ResponseWriter.Status = 500
			nspel.Error(err)
			return
		}
		student := new(entity.Student)
		err = student.SelectAllById(scores[i].StudentId)
		if err != nil {
			c.Ctx.ResponseWriter.Status = 500
			nspel.Error(err)
			return
		}
		xlsx.SetCellValue("体质", "A"+strconv.Itoa(i+2), school.SchoolCode)
		widthMap["A"] = math.Max(widthMap["A"], util.GetStrLength(school.SchoolCode)+1)
		xlsx.SetCellValue("体质", "B"+strconv.Itoa(i+2), scores[i].Grade)
		widthMap["B"] = math.Max(widthMap["B"], util.GetStrLength(scores[i].Grade)+1)
		xlsx.SetCellValue("体质", "C"+strconv.Itoa(i+2), scores[i].Class)
		widthMap["C"] = math.Max(widthMap["C"], util.GetStrLength(scores[i].Class)+1)
		xlsx.SetCellValue("体质", "D"+strconv.Itoa(i+2), scores[i].SchoolRollId)
		widthMap["D"] = math.Max(widthMap["D"], util.GetStrLength(scores[i].SchoolRollId)+1)
		xlsx.SetCellValue("体质", "E"+strconv.Itoa(i+2), scores[i].Nation)
		widthMap["E"] = math.Max(widthMap["E"], util.GetStrLength(scores[i].Nation)+1)
		xlsx.SetCellValue("体质", "F"+strconv.Itoa(i+2), student.Name)
		widthMap["F"] = math.Max(widthMap["F"], util.GetStrLength(student.Name)+1)
		xlsx.SetCellValue("体质", "G"+strconv.Itoa(i+2), scores[i].Sex)
		widthMap["G"] = math.Max(widthMap["G"], util.GetStrLength("1")+1)
		if !student.Birthday.IsZero() {
			xlsx.SetCellValue("体质", "H"+strconv.Itoa(i+2), student.Birthday.Format("2006/01/02"))
			widthMap["H"] = math.Max(widthMap["H"], util.GetStrLength(student.Birthday.Format("2006/01/02"))+1)
		}
		xlsx.SetCellValue("体质", "I"+strconv.Itoa(i+2), student.IdentityId.String)
		widthMap["I"] = math.Max(widthMap["I"], util.GetStrLength(student.IdentityId.String)+1)
		xlsx.SetCellValue("体质", "J"+strconv.Itoa(i+2), student.StudentId)
		widthMap["J"] = math.Max(widthMap["J"], util.GetStrLength(student.StudentId)+1)
		xlsx.SetCellValue("体质", "K"+strconv.Itoa(i+2), util.GetBoolString(scores[i].IsSupplementary, "是", "否"))
		widthMap["K"] = math.Max(widthMap["K"], util.GetStrLength("是")+1)
		xlsx.SetCellValue("体质", "L"+strconv.Itoa(i+2), util.GetBoolString(scores[i].IsExemption, "是", "否"))
		widthMap["L"] = math.Max(widthMap["L"], util.GetStrLength("是")+1)
		if scores[i].Height.Valid {
			xlsx.SetCellValue("体质", "M"+strconv.Itoa(i+2), scores[i].Height.Float64)
			widthMap["M"] = math.Max(widthMap["M"], util.GetStrLength(strconv.FormatFloat(scores[i].Height.Float64, 'f', -1, 64))+1)
		}
		if scores[i].Weight.Valid {
			xlsx.SetCellValue("体质", "N"+strconv.Itoa(i+2), scores[i].Weight.Float64)
			widthMap["N"] = math.Max(widthMap["N"], util.GetStrLength(strconv.FormatFloat(scores[i].Weight.Float64, 'f', -1, 64))+1)
		}
		if scores[i].BodyMassIndex.Valid {
			xlsx.SetCellValue("体质", "O"+strconv.Itoa(i+2), scores[i].BodyMassIndex.Float64)
			widthMap["O"] = math.Max(widthMap["O"], util.GetStrLength(strconv.FormatFloat(scores[i].BodyMassIndex.Float64, 'f', -1, 64))+1)
		}
		if scores[i].BodyMassIndexBasicScore.Valid {
			xlsx.SetCellValue("体质", "P"+strconv.Itoa(i+2), scores[i].BodyMassIndexBasicScore.Float64)
			widthMap["P"] = math.Max(widthMap["P"], util.GetStrLength(strconv.FormatFloat(scores[i].BodyMassIndexBasicScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].BodyMassIndexExtraScore.Valid {
			xlsx.SetCellValue("体质", "Q"+strconv.Itoa(i+2), scores[i].BodyMassIndexExtraScore.Float64)
			widthMap["Q"] = math.Max(widthMap["Q"], util.GetStrLength(strconv.FormatFloat(scores[i].BodyMassIndexExtraScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].BodyMassIndexTotalScore.Valid {
			xlsx.SetCellValue("体质", "R"+strconv.Itoa(i+2), scores[i].BodyMassIndexTotalScore.Float64)
			widthMap["R"] = math.Max(widthMap["R"], util.GetStrLength(strconv.FormatFloat(scores[i].BodyMassIndexTotalScore.Float64, 'f', -1, 64))+1)
		}
		if len(scores[i].BodyMassIndexLevel.String) > 0 {
			xlsx.SetCellValue("体质", "S"+strconv.Itoa(i+2), scores[i].BodyMassIndexLevel.String)
			widthMap["S"] = math.Max(widthMap["S"], util.GetStrLength(scores[i].BodyMassIndexLevel.String)+1)
		}
		if scores[i].VitalCapacity.Valid {
			xlsx.SetCellValue("体质", "T"+strconv.Itoa(i+2), scores[i].VitalCapacity.Float64)
			widthMap["T"] = math.Max(widthMap["T"], util.GetStrLength(strconv.FormatFloat(scores[i].VitalCapacity.Float64, 'f', -1, 64))+1)
		}
		if scores[i].VitalCapacityBasicScore.Valid {
			xlsx.SetCellValue("体质", "U"+strconv.Itoa(i+2), scores[i].VitalCapacityBasicScore.Float64)
			widthMap["U"] = math.Max(widthMap["U"], util.GetStrLength(strconv.FormatFloat(scores[i].VitalCapacityBasicScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].VitalCapacityExtraScore.Valid {
			xlsx.SetCellValue("体质", "V"+strconv.Itoa(i+2), scores[i].VitalCapacityExtraScore.Float64)
			widthMap["V"] = math.Max(widthMap["V"], util.GetStrLength(strconv.FormatFloat(scores[i].VitalCapacityExtraScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].VitalCapacityTotalScore.Valid {
			xlsx.SetCellValue("体质", "W"+strconv.Itoa(i+2), scores[i].VitalCapacityTotalScore.Float64)
			widthMap["W"] = math.Max(widthMap["W"], util.GetStrLength(strconv.FormatFloat(scores[i].VitalCapacityTotalScore.Float64, 'f', -1, 64))+1)
		}
		if len(scores[i].VitalCapacityLevel.String) > 0 {
			xlsx.SetCellValue("体质", "X"+strconv.Itoa(i+2), scores[i].VitalCapacityLevel.String)
			widthMap["X"] = math.Max(widthMap["X"], util.GetStrLength(scores[i].VitalCapacityLevel.String)+1)
		}
		if scores[i].FiftyMeters.Valid {
			xlsx.SetCellValue("体质", "Y"+strconv.Itoa(i+2), scores[i].FiftyMeters.Float64)
			widthMap["Y"] = math.Max(widthMap["Y"], util.GetStrLength(strconv.FormatFloat(scores[i].FiftyMeters.Float64, 'f', -1, 64))+1)
		}
		if scores[i].FiftyMetersBasicScore.Valid {
			xlsx.SetCellValue("体质", "Z"+strconv.Itoa(i+2), scores[i].FiftyMetersBasicScore.Float64)
			widthMap["Z"] = math.Max(widthMap["Z"], util.GetStrLength(strconv.FormatFloat(scores[i].FiftyMetersBasicScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].FiftyMetersExtraScore.Valid {
			xlsx.SetCellValue("体质", "AA"+strconv.Itoa(i+2), scores[i].FiftyMetersExtraScore.Float64)
			widthMap["AA"] = math.Max(widthMap["AA"], util.GetStrLength(strconv.FormatFloat(scores[i].FiftyMetersExtraScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].FiftyMetersTotalScore.Valid {
			xlsx.SetCellValue("体质", "AB"+strconv.Itoa(i+2), scores[i].FiftyMetersTotalScore.Float64)
			widthMap["AB"] = math.Max(widthMap["AB"], util.GetStrLength(strconv.FormatFloat(scores[i].FiftyMetersTotalScore.Float64, 'f', -1, 64))+1)
		}
		if len(scores[i].FiftyMetersLevel.String) > 0 {
			xlsx.SetCellValue("体质", "AC"+strconv.Itoa(i+2), scores[i].FiftyMetersLevel.String)
			widthMap["AC"] = math.Max(widthMap["AC"], util.GetStrLength(scores[i].FiftyMetersLevel.String)+1)
		}
		if scores[i].SitAndReach.Valid {
			xlsx.SetCellValue("体质", "AD"+strconv.Itoa(i+2), scores[i].SitAndReach.Float64)
			widthMap["AD"] = math.Max(widthMap["AD"], util.GetStrLength(strconv.FormatFloat(scores[i].SitAndReach.Float64, 'f', -1, 64))+1)
		}
		if scores[i].SitAndReachBasicScore.Valid {
			xlsx.SetCellValue("体质", "AE"+strconv.Itoa(i+2), scores[i].SitAndReachBasicScore.Float64)
			widthMap["AE"] = math.Max(widthMap["AE"], util.GetStrLength(strconv.FormatFloat(scores[i].SitAndReachBasicScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].SitAndReachExtraScore.Valid {
			xlsx.SetCellValue("体质", "AF"+strconv.Itoa(i+2), scores[i].SitAndReachExtraScore.Float64)
			widthMap["AF"] = math.Max(widthMap["AF"], util.GetStrLength(strconv.FormatFloat(scores[i].SitAndReachExtraScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].SitAndReachTotalScore.Valid {
			xlsx.SetCellValue("体质", "AG"+strconv.Itoa(i+2), scores[i].SitAndReachTotalScore.Float64)
			widthMap["AG"] = math.Max(widthMap["AG"], util.GetStrLength(strconv.FormatFloat(scores[i].SitAndReachTotalScore.Float64, 'f', -1, 64))+1)
		}
		if len(scores[i].SitAndReachLevel.String) > 0 {
			xlsx.SetCellValue("体质", "AH"+strconv.Itoa(i+2), scores[i].SitAndReachLevel.String)
			widthMap["AH"] = math.Max(widthMap["AH"], util.GetStrLength(scores[i].SitAndReachLevel.String)+1)
		}
		if scores[i].ShuttleRun.Valid {
			xlsx.SetCellValue("体质", "AI"+strconv.Itoa(i+2), util.TransIntToTime(int64(scores[i].ShuttleRun.Float64)))
			widthMap["AI"] = math.Max(widthMap["AI"], util.GetStrLength(util.TransIntToTime(int64(scores[i].ShuttleRun.Float64)))+1)
		}
		if scores[i].ShuttleRunBasicScore.Valid {
			xlsx.SetCellValue("体质", "AJ"+strconv.Itoa(i+2), scores[i].ShuttleRunBasicScore.Float64)
			widthMap["AJ"] = math.Max(widthMap["AJ"], util.GetStrLength(strconv.FormatFloat(scores[i].ShuttleRunBasicScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].ShuttleRunExtraScore.Valid {
			xlsx.SetCellValue("体质", "AK"+strconv.Itoa(i+2), scores[i].ShuttleRunExtraScore.Float64)
			widthMap["AK"] = math.Max(widthMap["AK"], util.GetStrLength(strconv.FormatFloat(scores[i].ShuttleRunExtraScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].ShuttleRunTotalScore.Valid {
			xlsx.SetCellValue("体质", "AL"+strconv.Itoa(i+2), scores[i].ShuttleRunTotalScore.Float64)
			widthMap["AL"] = math.Max(widthMap["AL"], util.GetStrLength(strconv.FormatFloat(scores[i].ShuttleRunTotalScore.Float64, 'f', -1, 64))+1)
		}
		if len(scores[i].ShuttleRunLevel.String) > 0 {
			xlsx.SetCellValue("体质", "AM"+strconv.Itoa(i+2), scores[i].ShuttleRunLevel.String)
			widthMap["AM"] = math.Max(widthMap["AM"], util.GetStrLength(scores[i].ShuttleRunLevel.String)+1)
		}
		if scores[i].OneMinuteSitUp.Valid {
			xlsx.SetCellValue("体质", "AN"+strconv.Itoa(i+2), scores[i].OneMinuteSitUp.Float64)
			widthMap["AN"] = math.Max(widthMap["AN"], util.GetStrLength(strconv.FormatFloat(scores[i].OneMinuteSitUp.Float64, 'f', -1, 64))+1)
		}
		if scores[i].OneMinuteSitUpBasicScore.Valid {
			xlsx.SetCellValue("体质", "AO"+strconv.Itoa(i+2), scores[i].OneMinuteSitUpBasicScore.Float64)
			widthMap["AO"] = math.Max(widthMap["AO"], util.GetStrLength(strconv.FormatFloat(scores[i].OneMinuteSitUpBasicScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].OneMinuteSitUpExtraScore.Valid {
			xlsx.SetCellValue("体质", "AP"+strconv.Itoa(i+2), scores[i].OneMinuteSitUpExtraScore.Float64)
			widthMap["AP"] = math.Max(widthMap["AP"], util.GetStrLength(strconv.FormatFloat(scores[i].OneMinuteSitUpExtraScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].OneMinuteSitUpTotalScore.Valid {
			xlsx.SetCellValue("体质", "AQ"+strconv.Itoa(i+2), scores[i].OneMinuteSitUpTotalScore.Float64)
			widthMap["AQ"] = math.Max(widthMap["AQ"], util.GetStrLength(strconv.FormatFloat(scores[i].OneMinuteSitUpTotalScore.Float64, 'f', -1, 64))+1)
		}
		if len(scores[i].OneMinuteSitUpLevel.String) > 0 {
			xlsx.SetCellValue("体质", "AR"+strconv.Itoa(i+2), scores[i].OneMinuteSitUpLevel.String)
			widthMap["AR"] = math.Max(widthMap["AR"], util.GetStrLength(scores[i].OneMinuteSitUpLevel.String)+1)
		}
		if scores[i].OneMinuteRopeSkipping.Valid {
			xlsx.SetCellValue("体质", "AS"+strconv.Itoa(i+2), scores[i].OneMinuteRopeSkipping.Float64)
			widthMap["AS"] = math.Max(widthMap["AS"], util.GetStrLength(strconv.FormatFloat(scores[i].OneMinuteRopeSkipping.Float64, 'f', -1, 64))+1)
		}
		if scores[i].OneMinuteRopeSkippingBasicScore.Valid {
			xlsx.SetCellValue("体质", "AT"+strconv.Itoa(i+2), scores[i].OneMinuteRopeSkippingBasicScore.Float64)
			widthMap["AT"] = math.Max(widthMap["AT"], util.GetStrLength(strconv.FormatFloat(scores[i].OneMinuteRopeSkippingBasicScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].OneMinuteRopeSkippingExtraScore.Valid {
			xlsx.SetCellValue("体质", "AU"+strconv.Itoa(i+2), scores[i].OneMinuteRopeSkippingExtraScore.Float64)
			widthMap["AU"] = math.Max(widthMap["AU"], util.GetStrLength(strconv.FormatFloat(scores[i].OneMinuteRopeSkippingExtraScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].OneMinuteRopeSkippingTotalScore.Valid {
			xlsx.SetCellValue("体质", "AV"+strconv.Itoa(i+2), scores[i].OneMinuteRopeSkippingTotalScore.Float64)
			widthMap["AV"] = math.Max(widthMap["AV"], util.GetStrLength(strconv.FormatFloat(scores[i].OneMinuteRopeSkippingTotalScore.Float64, 'f', -1, 64))+1)
		}
		if len(scores[i].OneMinuteRopeSkippingLevel.String) > 0 {
			xlsx.SetCellValue("体质", "AW"+strconv.Itoa(i+2), scores[i].OneMinuteRopeSkippingLevel.String)
			widthMap["AW"] = math.Max(widthMap["AW"], util.GetStrLength(scores[i].OneMinuteRopeSkippingLevel.String)+1)
		}
		if scores[i].StandingLongJump.Valid {
			xlsx.SetCellValue("体质", "AX"+strconv.Itoa(i+2), scores[i].StandingLongJump.Float64)
			widthMap["AX"] = math.Max(widthMap["AX"], util.GetStrLength(strconv.FormatFloat(scores[i].StandingLongJump.Float64, 'f', -1, 64))+1)
		}
		if scores[i].StandingLongJumpBasicScore.Valid {
			xlsx.SetCellValue("体质", "AY"+strconv.Itoa(i+2), scores[i].StandingLongJumpBasicScore.Float64)
			widthMap["AY"] = math.Max(widthMap["AY"], util.GetStrLength(strconv.FormatFloat(scores[i].StandingLongJumpBasicScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].StandingLongJumpExtraScore.Valid {
			xlsx.SetCellValue("体质", "AZ"+strconv.Itoa(i+2), scores[i].StandingLongJumpExtraScore.Float64)
			widthMap["AZ"] = math.Max(widthMap["AZ"], util.GetStrLength(strconv.FormatFloat(scores[i].StandingLongJumpExtraScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].StandingLongJumpTotalScore.Valid {
			xlsx.SetCellValue("体质", "BA"+strconv.Itoa(i+2), scores[i].StandingLongJumpTotalScore.Float64)
			widthMap["BA"] = math.Max(widthMap["BA"], util.GetStrLength(strconv.FormatFloat(scores[i].StandingLongJumpTotalScore.Float64, 'f', -1, 64))+1)
		}
		if len(scores[i].StandingLongJumpLevel.String) > 0 {
			xlsx.SetCellValue("体质", "BB"+strconv.Itoa(i+2), scores[i].StandingLongJumpLevel.String)
			widthMap["BB"] = math.Max(widthMap["BB"], util.GetStrLength(scores[i].StandingLongJumpLevel.String)+1)
		}
		if scores[i].EightHundredMeters.Valid {
			xlsx.SetCellValue("体质", "BC"+strconv.Itoa(i+2), util.TransIntToTime(int64(scores[i].EightHundredMeters.Float64)))
			widthMap["BC"] = math.Max(widthMap["BC"], util.GetStrLength(util.TransIntToTime(int64(scores[i].EightHundredMeters.Float64)))+1)
		}
		if scores[i].EightHundredMetersBasicScore.Valid {
			xlsx.SetCellValue("体质", "BD"+strconv.Itoa(i+2), scores[i].EightHundredMetersBasicScore.Float64)
			widthMap["BD"] = math.Max(widthMap["BD"], util.GetStrLength(strconv.FormatFloat(scores[i].EightHundredMetersBasicScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].EightHundredMetersExtraScore.Valid {
			xlsx.SetCellValue("体质", "BE"+strconv.Itoa(i+2), scores[i].EightHundredMetersExtraScore.Float64)
			widthMap["BE"] = math.Max(widthMap["BE"], util.GetStrLength(strconv.FormatFloat(scores[i].EightHundredMetersExtraScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].EightHundredMetersTotalScore.Valid {
			xlsx.SetCellValue("体质", "BF"+strconv.Itoa(i+2), scores[i].EightHundredMetersTotalScore.Float64)
			widthMap["BF"] = math.Max(widthMap["BF"], util.GetStrLength(strconv.FormatFloat(scores[i].EightHundredMetersTotalScore.Float64, 'f', -1, 64))+1)
		}
		if len(scores[i].EightHundredMetersLevel.String) > 0 {
			xlsx.SetCellValue("体质", "BG"+strconv.Itoa(i+2), scores[i].EightHundredMetersLevel.String)
			widthMap["BG"] = math.Max(widthMap["BG"], util.GetStrLength(scores[i].EightHundredMetersLevel.String)+1)
		}
		if scores[i].OneThousandMeters.Valid {
			xlsx.SetCellValue("体质", "BH"+strconv.Itoa(i+2), util.TransIntToTime(int64(scores[i].OneThousandMeters.Float64)))
			widthMap["BH"] = math.Max(widthMap["BH"], util.GetStrLength(util.TransIntToTime(int64(scores[i].OneThousandMeters.Float64)))+1)
		}
		if scores[i].OneThousandMetersBasicScore.Valid {
			xlsx.SetCellValue("体质", "BI"+strconv.Itoa(i+2), scores[i].OneThousandMetersBasicScore.Float64)
			widthMap["BI"] = math.Max(widthMap["BI"], util.GetStrLength(strconv.FormatFloat(scores[i].OneThousandMetersBasicScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].OneThousandMetersExtraScore.Valid {
			xlsx.SetCellValue("体质", "BJ"+strconv.Itoa(i+2), scores[i].OneThousandMetersExtraScore.Float64)
			widthMap["BJ"] = math.Max(widthMap["BJ"], util.GetStrLength(strconv.FormatFloat(scores[i].OneThousandMetersExtraScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].OneThousandMetersTotalScore.Valid {
			xlsx.SetCellValue("体质", "BK"+strconv.Itoa(i+2), scores[i].OneThousandMetersTotalScore.Float64)
			widthMap["BK"] = math.Max(widthMap["BK"], util.GetStrLength(strconv.FormatFloat(scores[i].OneThousandMetersTotalScore.Float64, 'f', -1, 64))+1)
		}
		if len(scores[i].OneThousandMetersLevel.String) > 0 {
			xlsx.SetCellValue("体质", "BL"+strconv.Itoa(i+2), scores[i].OneThousandMetersLevel.String)
			widthMap["BL"] = math.Max(widthMap["BL"], util.GetStrLength(scores[i].OneThousandMetersLevel.String)+1)
		}
		if scores[i].Chinning.Valid {
			xlsx.SetCellValue("体质", "BM"+strconv.Itoa(i+2), scores[i].Chinning.Float64)
			widthMap["BM"] = math.Max(widthMap["BM"], util.GetStrLength(strconv.FormatFloat(scores[i].Chinning.Float64, 'f', -1, 64))+1)
		}
		if scores[i].ChinningBasicScore.Valid {
			xlsx.SetCellValue("体质", "BN"+strconv.Itoa(i+2), scores[i].ChinningBasicScore.Float64)
			widthMap["BN"] = math.Max(widthMap["BN"], util.GetStrLength(strconv.FormatFloat(scores[i].ChinningBasicScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].ChinningExtraScore.Valid {
			xlsx.SetCellValue("体质", "BO"+strconv.Itoa(i+2), scores[i].ChinningExtraScore.Float64)
			widthMap["BO"] = math.Max(widthMap["BO"], util.GetStrLength(strconv.FormatFloat(scores[i].ChinningExtraScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].ChinningTotalScore.Valid {
			xlsx.SetCellValue("体质", "BP"+strconv.Itoa(i+2), scores[i].ChinningTotalScore.Float64)
			widthMap["BP"] = math.Max(widthMap["BP"], util.GetStrLength(strconv.FormatFloat(scores[i].ChinningTotalScore.Float64, 'f', -1, 64))+1)
		}
		if len(scores[i].ChinningLevel.String) > 0 {
			xlsx.SetCellValue("体质", "BQ"+strconv.Itoa(i+2), scores[i].ChinningLevel.String)
			widthMap["BQ"] = math.Max(widthMap["BQ"], util.GetStrLength(scores[i].ChinningLevel.String)+1)
		}
		if scores[i].BodyFat.Valid {
			xlsx.SetCellValue("体质", "BR"+strconv.Itoa(i+2), scores[i].BodyFat.Float64)
			widthMap["BR"] = math.Max(widthMap["BR"], util.GetStrLength(strconv.FormatFloat(scores[i].BodyFat.Float64, 'f', -1, 64))+1)
		}
		if len(scores[i].BodyFatLevel.String) > 0 {
			xlsx.SetCellValue("体质", "BS"+strconv.Itoa(i+2), scores[i].BodyFatLevel.String)
			widthMap["BS"] = math.Max(widthMap["BS"], util.GetStrLength(scores[i].BodyFatLevel.String)+1)
		}
		if scores[i].GripStrength.Valid {
			xlsx.SetCellValue("体质", "BT"+strconv.Itoa(i+2), scores[i].GripStrength.Float64)
			widthMap["BT"] = math.Max(widthMap["BT"], util.GetStrLength(strconv.FormatFloat(scores[i].GripStrength.Float64, 'f', -1, 64))+1)
		}
		if len(scores[i].GripStrengthLevel.String) > 0 {
			xlsx.SetCellValue("体质", "BT"+strconv.Itoa(i+2), scores[i].GripStrengthLevel.String)
			widthMap["BT"] = math.Max(widthMap["BT"], util.GetStrLength(scores[i].GripStrengthLevel.String)+1)
		}
		if scores[i].ResponseCapability.Valid {
			xlsx.SetCellValue("体质", "BV"+strconv.Itoa(i+2), scores[i].ResponseCapability.Float64)
			widthMap["BV"] = math.Max(widthMap["BV"], util.GetStrLength(strconv.FormatFloat(scores[i].ResponseCapability.Float64, 'f', -1, 64))+1)
		}
		if len(scores[i].ResponseCapabilityLevel.String) > 0 {
			xlsx.SetCellValue("体质", "BW"+strconv.Itoa(i+2), scores[i].ResponseCapabilityLevel.String)
			widthMap["BW"] = math.Max(widthMap["BW"], util.GetStrLength(scores[i].ResponseCapabilityLevel.String)+1)
		}
		if scores[i].BalanceAbility.Valid {
			xlsx.SetCellValue("体质", "BX"+strconv.Itoa(i+2), scores[i].BalanceAbility.Float64)
			widthMap["BX"] = math.Max(widthMap["BX"], util.GetStrLength(strconv.FormatFloat(scores[i].BalanceAbility.Float64, 'f', -1, 64))+1)
		}
		if len(scores[i].BalanceAbilityLevel.String) > 0 {
			xlsx.SetCellValue("体质", "BY"+strconv.Itoa(i+2), scores[i].BalanceAbilityLevel.String)
			widthMap["BY"] = math.Max(widthMap["BY"], util.GetStrLength(scores[i].BalanceAbilityLevel.String)+1)
		}
		if scores[i].VerticalJump.Valid {
			xlsx.SetCellValue("体质", "BZ"+strconv.Itoa(i+2), scores[i].VerticalJump.Float64)
			widthMap["BZ"] = math.Max(widthMap["BZ"], util.GetStrLength(strconv.FormatFloat(scores[i].VerticalJump.Float64, 'f', -1, 64))+1)
		}
		if len(scores[i].VerticalJumpLevel.String) > 0 {
			xlsx.SetCellValue("体质", "CA"+strconv.Itoa(i+2), scores[i].VerticalJumpLevel.String)
			widthMap["CA"] = math.Max(widthMap["CA"], util.GetStrLength(scores[i].VerticalJumpLevel.String)+1)
		}
		if scores[i].PhysicalBasicScore.Valid {
			xlsx.SetCellValue("体质", "CB"+strconv.Itoa(i+2), scores[i].PhysicalBasicScore.Float64)
			widthMap["CB"] = math.Max(widthMap["CB"], util.GetStrLength(strconv.FormatFloat(scores[i].PhysicalBasicScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].PhysicalExtraScore.Valid {
			xlsx.SetCellValue("体质", "CC"+strconv.Itoa(i+2), scores[i].PhysicalExtraScore.Float64)
			widthMap["CC"] = math.Max(widthMap["CC"], util.GetStrLength(strconv.FormatFloat(scores[i].PhysicalExtraScore.Float64, 'f', -1, 64))+1)
		}
		if scores[i].PhysicalTotalScore.Valid {
			xlsx.SetCellValue("体质", "CD"+strconv.Itoa(i+2), scores[i].PhysicalTotalScore.Float64)
			widthMap["CD"] = math.Max(widthMap["CD"], util.GetStrLength(strconv.FormatFloat(scores[i].PhysicalTotalScore.Float64, 'f', -1, 64))+1)
		}
		xlsx.SetCellValue("体质", "CE"+strconv.Itoa(i+2), int(scores[i].MissingTestNum))
		widthMap["CE"] = math.Max(widthMap["CE"], util.GetStrLength(strconv.Itoa(int(scores[i].MissingTestNum)))+1)
	}
	for k, v := range widthMap {
		xlsx.SetColWidth("体质", k, k, v)
	}
	buffer, err := xlsx.WriteToBuffer()
	if err != nil {
		c.Ctx.ResponseWriter.Status = 500
		nspel.Error(err)
		return
	}
	c.Ctx.Output.Header("Content-Disposition", "attachment; filename="+url.PathEscape("体质.xlsx"))
	c.Ctx.Output.Header("Content-Description", "File Transfer")
	c.Ctx.Output.Header("Content-Type", "application/octet-stream")
	c.Ctx.Output.Header("Content-Transfer-Encoding", "binary")
	c.Ctx.Output.Header("Expires", "0")
	c.Ctx.Output.Header("Cache-Control", "must-revalidate")
	c.Ctx.Output.Header("Pragma", "public")
	c.Ctx.ResponseWriter.Write(buffer.Bytes())
}
